home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / vax / __longjmp.c < prev    next >
C/C++ Source or Header  |  1992-03-11  |  3KB  |  101 lines

  1. /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  2.    Derived from @(#)_setjmp.s    5.7 (Berkeley) 6/27/88,
  3.    Copyright (c) 1980 Regents of the University of California.
  4.  
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9.  
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with the GNU C Library; see the file COPYING.LIB.  If
  17. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  18. Cambridge, MA 02139, USA.  */
  19.  
  20. #include <ansidecl.h>
  21. #include <setjmp.h>
  22.  
  23. #ifndef    __GNUC__
  24.   #error This file uses GNU C extensions; you must compile with GCC.
  25. #endif
  26.  
  27.  
  28. #define    REI    02    /* Vax `rei' opcode.  */
  29.  
  30. /* Jump to the position specified by ENV, causing the
  31.    setjmp call there to return VAL, or 1 if VAL is 0.  */
  32. __NORETURN
  33. void
  34. DEFUN(__longjmp, (env, val), CONST jmp_buf env AND int val)
  35. {
  36.   register long int *fp asm("fp");
  37.   long int *regsave;
  38.   unsigned long int flags;
  39.  
  40.   if (env.__fp == NULL)
  41.     __libc_fatal("longjmp: Invalid ENV argument.\n");
  42.  
  43.   if (val == 0)
  44.     val = 1;
  45.  
  46.   asm volatile("loop:");
  47.  
  48.   flags = *(long int *) (6 + (char *) fp);
  49.   regsave = (long int *) (20 + (char *) fp);
  50.   if (flags & 1)
  51.     /* R0 was saved by the caller.
  52.        Store VAL where it will be restored from.  */
  53.     *regsave++ = val;
  54.   if (flags & 2)
  55.     /* R1 was saved by the caller.
  56.        Store ENV where it will be restored from.  */
  57.     *regsave = env;
  58.  
  59.   /* Was the FP saved in the last call the same one in ENV?  */
  60.   asm volatile("cmpl %0, 12(fp);"
  61.            /* Yes, return to it.  */
  62.            "beql done;"
  63.            /* The FP in ENV is less than the one saved in the last call.
  64.           This means we have already returned from the function that
  65.           called `setjmp' with ENV!  */
  66.            "blssu latejump;" : /* No outputs.  */ : "g" (env.__fp));
  67.  
  68.   /* We are more than one level below the state in ENV.
  69.      Return to where we will pop another stack frame.  */
  70.   asm volatile("movl $loop, 16(fp);"
  71.            "ret");
  72.  
  73.   asm volatile("done:");
  74.   {
  75.     char return_insn asm("*16(fp)");
  76.     if (return_insn == REI)
  77.       /* We're returning with an `rei' instruction.
  78.      Do a return with PSL-PC pop.  */
  79.       asm volatile("movab 0f, 16(fp)");
  80.     else
  81.       /* Do a standard return.  */
  82.       asm volatile("movab 1f, 16(fp)");
  83.  
  84.     /* Return.  */
  85.     asm volatile("ret");
  86.   }
  87.  
  88.   asm volatile("0:"    /* `rei' return.  */
  89.            /* Compensate for PSL-PC push.  */
  90.            "addl2 %0, sp;"
  91.            "1:"    /* Standard return.  */
  92.            /* Return to saved PC.  */
  93.            "jmp %1" : /* No outputs.  */ :
  94.            "g" (8), "g" (env.__pc));
  95.  
  96.   /* Jump here when the FP saved in ENV points
  97.      to a function that has already returned.  */
  98.   asm volatile("latejump:");
  99.   __libc_fatal("longjmp: Attempt to jump to a function that has returned.\n");
  100. }
  101.